#ifndef METRICS_H
#define METRICS_H

#include <string>
#include <unordered_map>
#include <vector>
#include <mutex>
#include <memory>
#include <chrono>
#include <atomic>
#include <limits>

// 指标类型
enum class MetricType {
    COUNTER,   // 只增不减的计数器
    GAUGE,     // 可增可减的仪表盘
    HISTOGRAM, // 直方图，用于分布式统计
    TIMER      // 计时器，特殊的直方图
};

// 基础指标类
class Metric {
public:
    Metric(const std::string& name, const std::string& help, 
           const std::unordered_map<std::string, std::string>& labels = {});
    virtual ~Metric() = default;
    
    // 获取指标名称
    const std::string& getName() const;
    
    // 获取帮助信息
    const std::string& getHelp() const;
    
    // 获取标签
    const std::unordered_map<std::string, std::string>& getLabels() const;
    
    // 获取指标类型
    virtual MetricType getType() const = 0;
    
    // 导出指标值（由子类实现）
    virtual std::string exportMetric() const = 0;
    
protected:
    std::string name_;
    std::string help_;
    std::unordered_map<std::string, std::string> labels_;
};

// 计数器指标
class Counter : public Metric {
public:
    Counter(const std::string& name, const std::string& help, 
            const std::unordered_map<std::string, std::string>& labels = {});
    
    // 增加计数
    void inc(double value = 1.0);
    
    // 获取当前值
    double getValue() const;
    
    // 实现基类方法
    MetricType getType() const override;
    std::string exportMetric() const override;
    
private:
    std::atomic<double> value_;
};

// 仪表盘指标
class Gauge : public Metric {
public:
    Gauge(const std::string& name, const std::string& help, 
          const std::unordered_map<std::string, std::string>& labels = {});
    
    // 设置值
    void set(double value);
    
    // 增加值
    void inc(double value = 1.0);
    
    // 减少值
    void dec(double value = 1.0);
    
    // 获取当前值
    double getValue() const;
    
    // 实现基类方法
    MetricType getType() const override;
    std::string exportMetric() const override;
    
private:
    std::atomic<double> value_;
};

// 直方图桶
struct HistogramBucket {
    double upperBound;
    std::atomic<uint64_t> count;
    
    explicit HistogramBucket(double bound) : upperBound(bound), count(0) {}
    
    // 添加拷贝构造函数
    HistogramBucket(const HistogramBucket& other) : upperBound(other.upperBound), count(other.count.load()) {}
    
    // 添加移动构造函数
    HistogramBucket(HistogramBucket&& other) noexcept : upperBound(other.upperBound), count(other.count.load()) {}
    
    // 添加拷贝赋值运算符
    HistogramBucket& operator=(const HistogramBucket& other) {
        if (this != &other) {
            upperBound = other.upperBound;
            count.store(other.count.load());
        }
        return *this;
    }
    
    // 添加移动赋值运算符
    HistogramBucket& operator=(HistogramBucket&& other) noexcept {
        if (this != &other) {
            upperBound = other.upperBound;
            count.store(other.count.load());
        }
        return *this;
    }
};

// 直方图指标
class Histogram : public Metric {
public:
    Histogram(const std::string& name, const std::string& help, 
              const std::vector<double>& buckets = {0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10},
              const std::unordered_map<std::string, std::string>& labels = {});
    
    // 观察值
    void observe(double value);
    
    // 实现基类方法
    MetricType getType() const override;
    std::string exportMetric() const override;
    
protected:
    std::vector<HistogramBucket> buckets_;
    std::atomic<double> sum_;
    std::atomic<uint64_t> count_;
};

// 计时器（特殊的直方图）
class Timer : public Histogram {
public:
    Timer(const std::string& name, const std::string& help, 
          const std::unordered_map<std::string, std::string>& labels = {});
    
    // 开始计时
    void start();
    
    // 停止计时并记录
    void stop();
    
    // 创建一个RAII风格的计时器
    class TimeGuard {
    public:
        TimeGuard(Timer& timer);
        ~TimeGuard();
        
    private:
        Timer& timer_;
        std::chrono::time_point<std::chrono::high_resolution_clock> startTime_;
    };
    
    // 使用RAII风格计时
    TimeGuard time();
    
    // 实现基类方法
    MetricType getType() const override;
    
private:
    std::chrono::time_point<std::chrono::high_resolution_clock> startTime_;
    std::mutex mutex_;
};

// 指标注册表
class MetricRegistry {
public:
    static MetricRegistry& instance();
    
    // 注册指标
    void registerMetric(std::shared_ptr<Metric> metric);
    
    // 获取已注册的指标
    std::vector<std::shared_ptr<Metric>> getMetrics() const;
    
    // 清除所有指标
    void clear();
    
    // 导出所有指标
    std::string exportAllMetrics() const;
    
private:
    MetricRegistry() = default;
    ~MetricRegistry() = default;
    
    std::vector<std::shared_ptr<Metric>> metrics_;
    mutable std::mutex mutex_;
};

// 便捷方法
std::shared_ptr<Counter> createCounter(const std::string& name, const std::string& help,
                                     const std::unordered_map<std::string, std::string>& labels = {});
std::shared_ptr<Gauge> createGauge(const std::string& name, const std::string& help,
                                 const std::unordered_map<std::string, std::string>& labels = {});
std::shared_ptr<Histogram> createHistogram(const std::string& name, const std::string& help,
                                         const std::vector<double>& buckets = {0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10},
                                         const std::unordered_map<std::string, std::string>& labels = {});
std::shared_ptr<Timer> createTimer(const std::string& name, const std::string& help,
                                 const std::unordered_map<std::string, std::string>& labels = {});

// 宏定义，方便使用
#define METRIC_TIME(name, help) \
    static auto timer = createTimer(name, help); \
    auto timeGuard = timer->time()

#endif // METRICS_H 